package com.pz.cloud.framework.workflow.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.pz.cloud.framework.business.workflow.entity.TaskNodeAttr;
import com.pz.cloud.framework.business.workflow.entity.WaitDone;
import com.pz.cloud.framework.business.workflow.entity.WaitDoneUser;
import com.pz.cloud.framework.business.workflow.model.*;
import com.pz.cloud.framework.business.workflow.service.*;
import com.pz.cloud.framework.util.BizUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.TreeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@RestController
@RequestMapping("/workflow")
@Api(tags = "流程管理")
public class WorkflowController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IWorkflowService workflowService;
    @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private IWaitDoneService waitDoneService;
    @Autowired
    private IWaitDoneUserService waitDoneUserService;
    @Autowired
    private ITaskNodeAttrService taskNodeAttrService;
    @Autowired
    private IWorkflowTaskService workflowTaskService;

    /**
     * 导入新的流程定义
     *
     * @param request HttpServletRequest
     * @return 操作结果
     */
    @PostMapping("/importProcess")
    @ResponseBody
    @ApiOperation(value = "流程导入")
    public Result importProcess(HttpServletRequest request) {
        try {
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
            if (multipartResolver.isMultipart(request)) {
                MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
                Iterator<String> iter = multiRequest.getFileNames();

                MultipartFile file = null;

                while (iter.hasNext()) {

                    file = multiRequest.getFile(iter.next());
                    if (file != null) { //根据导入的流程定义文件部署流程
                        workflowService.deployProcess(file.getInputStream());
                    }

                }
            }

        } catch (Exception e) {
            return Result.error("部署新的activiti流程失败");
        }
        return Result.OK();
    }
    /**
     * 选择处理人
     *
     * @return 操作结果
     */
    @GetMapping("/userTreeList")
    @ResponseBody
    @ApiOperation(value = "选择处理人")
    public Result<List<TreeNode>> userTreeList( String taskKey) {
        List<TreeNode> ztreeNodes =  workflowService.selectDealUser(taskKey);
        return Result.OK(ztreeNodes);
    }


    @GetMapping("/queryFlowNodeDataByBizId")
    @ResponseBody
    @ApiOperation(value = "通过业务id获取下一步任务流程节点信息")
    public Result<TaskApproveModel> queryFlowNodeDataByBizId(@ApiParam(required = true) @RequestParam("bizId") String bizId){
        List<Task> list = processEngine.getTaskService().createTaskQuery().processInstanceBusinessKey(bizId).taskCandidateOrAssigned(BizUtil.getUserId()).orderByTaskCreateTime().desc().list();
        if(list!=null&&list.size()>0){
            return Result.OK(workflowService.queryFlowNodeData(list.get(0).getId()));
        }
        return Result.OK();
    }

    @GetMapping("/queryProcessRecordByBizId")
    @ResponseBody
    @ApiOperation(value = "根据业务id获取流程历史处理信息")
    public Result<IPage<ProcessRecordModel>> queryProcessRecordByBizId(@ApiParam(required = true) @RequestParam("bizId") String bizId){
        IPage<ProcessRecordModel> waitDones = waitDoneService.findByBizId(bizId);

        if(waitDones.getRecords()!=null){
            for (ProcessRecordModel record : waitDones.getRecords()) {
                if(StringUtils.isEmpty(record.getDealUserName())){
                    List<WaitDoneUser> waitDoneUsers = waitDoneUserService.findByWaitDoneId(record.getId());
                    if(!CollectionUtils.isEmpty(waitDoneUsers)){
                        record.setDealUserName(waitDoneUsers.get(0).getWaitUserName());
                    }
                }
            }
        }
        return Result.OK(waitDones);
    }


    @ApiOperation(value = "根据业务id获取流程图")
    @GetMapping("/showProcessImageByBizId")
    public void showProcessImageByBizId(@ApiParam(required = true) @RequestParam("bizId") String bizId, HttpServletResponse response) throws IOException {
        workflowService.showProcessImageByBizId(bizId,response.getOutputStream());
    }
    @ApiOperation(value = "根据业务流程定义key获取流程图")
    @GetMapping("/showProcessImageByProcessDefineKey")
    public void showProcessImageByProcessDefineKey(@ApiParam(required = true) @RequestParam("processDefineKey") String processDefineKey, HttpServletResponse response) throws IOException {
        workflowService.showProcessImageByProcessDefineKey(processDefineKey,response.getOutputStream());
    }

    @GetMapping("/definitionList")
    @ResponseBody
    @ApiOperation(value = "查询流程定义信息")
    public Result<IPage<ProcessBean>> definitionList(ProcessBean processBean){

        return Result.OK(workflowService.definitionPage(processBean));
    }

    @GetMapping("/taskNodeList")
    @ApiOperation(value = "根据流程定义id查询任务节点信息")
    public Result<List<TaskNodeModel>> taskNodeList(@ApiParam(required = true) @RequestParam("processDefinitionId")String processDefinitionId){
        List<TaskNodeModel> listFlowNode = workflowService.taskNodeList(processDefinitionId);
        return Result.OK(listFlowNode);
    }


    @AutoLog(value = "任务节点属性-添加|编辑")
    @ApiOperation(value = "任务节点属性-添加|编辑", notes = "任务节点属性-添加|编辑")
    @PostMapping(value = "/saveTaskNodeAttr")
    public Result saveTaskNodeAttr(@RequestBody TaskNodeAttr entity) {
        Result<TaskNodeAttr> result = new Result<>();
        taskNodeAttrService.save(entity);
        result.success("保存成功！");
        return result;
    }

    @AutoLog(value = "任务节点属性-查询")
    @ApiOperation(value = "任务节点属性-查询", notes = "任务节点属性-查询")
    @GetMapping(value = "/queryTaskNodeAttr")
    public Result<TaskNodeAttr> queryTaskNodeAttr(@ApiParam(required = true) @RequestParam("taskKey") String taskKey) {
        Result<TaskNodeAttr> result = new Result<>();
        TaskNodeAttr taskNodeAttr = taskNodeAttrService.getById(taskKey);
        return result.OK(taskNodeAttr);
    }

    @AutoLog(value = "批量处理任务")
    @ApiOperation(value = "批量处理任务", notes = "批量处理任务")
    @PostMapping(value = "/batchSubmitTask")
    public Result batchSubmitTask(@RequestBody JSONObject jsonObject){
        List<String> list = (List) jsonObject.get("bizId");
        Integer dealResult = (Integer) jsonObject.get("dealResult");
        if(!CollectionUtils.isEmpty(list)&&dealResult!=null){
            workflowService.batchSubmitTask(list,dealResult);
        }

        return Result.OK();
    }
    @AutoLog(value = "撤销流程")
    @ApiOperation(value = "撤销流程", notes = "撤销流程")
    @PostMapping(value = "/cancelProcess")
    public Result cancelProcess(@RequestBody JSONObject jsonObject){
        String bizId = (String) jsonObject.get("bizId");
        if(!StringUtils.isEmpty(bizId)){
            workflowService.deleteProcessByBizId(bizId,false);
        }
        return Result.OK();
    }


    @AutoLog(value = "撤回流程")
    @ApiOperation(value = "撤回流程", notes = "撤回流程")
    @PostMapping(value = "/withdrawProcess")
    public Result withdrawProcess(@RequestBody JSONObject jsonObject){

        String taskId = (String) jsonObject.get("taskId");
        if(!StringUtils.isEmpty(taskId)){
            workflowTaskService.withdrawTask(taskId);
        }
        return Result.OK();
    }
}
